using System.Collections;
using Evaluant.Uss.Commands;
using Evaluant.Uss.Common;
using System.Globalization;

namespace Evaluant.Uss.Remoting
{
	/// <summary>
	/// Simple Delegate Engine implementation to show the interception capabilities of the framework
	/// </summary>
	public class RemotingPersistenceEngine : IPersistenceEngine 
	{
		private RemoteController _RemoteEngine;
		public RemoteController RemoteEngine
		{
			get
			{
				return _RemoteEngine;
			}
		}

		public CultureInfo Culture
		{
			get { return null; }
			set { }
		}

		public RemotingPersistenceEngine(RemoteController remoteEngine)
		{
			_RemoteEngine = remoteEngine;
		}

		public EntitySet Load(string opath)
		{
			return Load(opath, new string[0]);
		}

		public EntitySet Load(string opath, string[] attributes)
		{
			return Load(opath, attributes, null, 1, 0);
		}

		public EntitySet Load(string opath, string orderby, int first, int max)
		{
			return Load(opath, new string[0], orderby, first, max);
		}

		public EntitySet LoadWithId(string type, string[] id)
		{
			return LoadWithId(type, id, new string[0]);
		}

		public Entity LoadWithId(string type, string id)
		{
			EntitySet result = LoadWithId(type, new string[] { id });
			return result.Count > 0 ? result[0] : null;
		}

		public void LoadReference(Entity entity)
		{
			LoadReference(new Entity[] { entity });
		}

		public void LoadReference(Entity entity, string[] references)
		{
			LoadReference(new Entity[] { entity }, references);
		}

		public void LoadReference(IEnumerable entities)
		{
			LoadReference(entities, new string[0]);
		}

		public void LoadReference(System.Collections.IEnumerable entities, string[] references)
		{
			IEnumerable TmpEntities = _RemoteEngine.LoadReference(entities, references);
			
			ArrayList al1 = new ArrayList();
			foreach(Entity e in entities)
				al1.Add(e);
			ArrayList al2 = new ArrayList();
			foreach(Entity e in TmpEntities)
				al2.Add(e);
			for(int i=0; i<al1.Count; i++)
			{
				((Entity)al1[i]).EntityEntries = ((Entity)al2[i]).EntityEntries;
			}
		}


		public void InitializeRepository()
		{
			_RemoteEngine.InitializeRepository();
		}

		public void Initialize()
		{
			_RemoteEngine.Initialize();			
		}

        public EntitySet Load(string opath, string[] attributes, string orderby, int first, int max)
        {
            return _RemoteEngine.Load(opath, attributes, orderby, first, max);
        }

        public EntitySet Load(Evaluant.OPath.OPathQuery opath, string[] attributes, string orderby, int first, int max)
        {
            return _RemoteEngine.Load(opath, attributes, orderby, first, max);
        }

		public EntitySet LoadWithId(string type, string[] id, string[] attributes)
		{
			return _RemoteEngine.LoadWithId(type, id, attributes);
		}

        public object LoadScalar(string opath)
        {
            return _RemoteEngine.LoadScalar(opath);
        }

        public object LoadScalar(OPath.OPathQuery opath)
        {
            return _RemoteEngine.LoadScalar(opath);
        }

		public void BeforeProcessCommands(Transaction tx)
		{
			Transaction remoteTx = _RemoteEngine.BeforeProcessCommands(tx);
			tx.NewIds = remoteTx.NewIds;
			tx.PendingCommands = remoteTx.PendingCommands;
		}

		public void ProcessCommands(Transaction tx)
		{
			Transaction remoteTx = _RemoteEngine.ProcessCommands(tx);
			tx.NewIds = remoteTx.NewIds;
			tx.PendingCommands = remoteTx.PendingCommands;
		}

		public void AfterProcessCommands(Transaction tx)
		{
			Transaction remoteTx = _RemoteEngine.AfterProcessCommands(tx);
			tx.NewIds = remoteTx.NewIds;
			tx.PendingCommands = remoteTx.PendingCommands;
		}

		public Evaluant.Uss.Models.Model Model
		{
			get { return _RemoteEngine.Model; }
		}
	}
}
